【MediaPipe】Multi Hand TrackingのGraphを解析してみた
カフェチームの山本です。
前回は、Multi Hand Trackingのプログラムの動作を解析しました。
今回は、Multi Hand TrackingのGraphを解析していきます。
(MediaPipeに関連する記事はこちらにまとめてあります。)
Multi Hand TrackingのGraph構造
前回、mediapipe/graphs/hand_tracking/multi_hand_tracking_desktop_live.pbtxt からGraphの構成が読み込まれて、実行されていることがわかりました。ここから、Multi Hand TrackingのGraphの構造と動作を見ていきます。
今回の内容は、DocとGitHubに記載されている画像や解説を参考にさせていただいています。(公開されているVisualizerにpbtxtファイルの内容をコピペすることで図示/可視化できます。ただし、そのままだとSubgraphは青色で表示されません。別タブでSubgraphをコピペすることでリンクされ、青色で表示されるようになります。)
Graph全体(multi_hand_tracking_desktop_live.pbtxt)
Graphの構成として以下のようになっていることがわかります。
- 入力Streamと出力Streamを1つずつもち、それぞれ"input_video"・"output_video"と名前である(この名前は呼び出すプログラムと同一になっていて、ImageFrameが入出力される)
- Nodeとして、4つのCalculator(白色のNode)と3つのSubgraph(青色のNode)がある。
- 大まかな処理の流れとして、
- MultiHandDetectionSubgraphで、手そのものの検出を行う
- MultiHandLandmarkSubgraphで、検出した手のRectに対して、手の骨格(Landmark)検出を行う
- MultiHandRendererSubgraphで、検出結果を描画する
- MultiHandLandmarkで手の骨格を検出できた手のRectを、次のフレームで利用するためにフィードバックさせる(MultiHandLandmarkから出てる点線部)
- NormalizedRectVectorHasMinSizeCalculatorで、前のフレームで検出した手の数が、設定された検出最小数よりも多いか判定し、多ければ手の検出を行わないように、GateCalculatorに指示を出す
- AssociationNormRectCalculatorで、前のフレームと現在のフレームで検出して手のRect同士で、重なりが大きいものを統合する
MultiHandLandmarkSubgraph(subgraph/multi_hand_landmark.pbtxt)
次に、MultiHandLandmarkSubgraphを見てみると、以下のことがわかります。
- 入力として、対象画像とMultiHandDetectionで検出された手のRect情報を受け取り、出力として、検出した骨格(landmark)情報と、骨格を検出できなかったものをフィルタリングした手のRect情報を返している。
- 入力の手のRectは複数受け取ることができ、BeginLoopNormalizedRectCalculatorが1つ1つ分解してPacket化して出力し、最後にBATCH_ENDを出力することで、ループ処理を可能にしている。
- HandLandmarkSubgraphで、画像を1つのRectを入力として受け取る。Rectで指定されたの画像内の領域に対して手の骨格検出を行い、その領域に手が存在するかどうか、骨格情報を出力する
- EndLoop---Calculatorで、BeginLoopNormalizedRectCalculatorで分解されて、それぞれのPacketに対してHandLandmarkSubgraphが出力する結果を保持する。BATCH_ENDを受け取ったら、保持していた結果を1つにまとめて、次のNodeに出力する。
HandLandmarkSubgraph(subgraph/hand_landmark_cpu.pbtxt)
HandLandmarkSubgraphを見てみると、以下のようになっています。
- ImageCroppingCalculatorによって、画像中のrectの部分を切り出す
- ImageTransformationCalculatorによって、予め設定されたサイズになるよう、切り出した画像を変形する
- TfLiteConverterCalculatorによって、画像をTensorに変換する
- TfLiteInferenceCalculatorによって、骨格を検出する
- (以降、検出した結果に対して、後処理を行う)
まとめ
Multi Hand TrackingがGraph構成を解析しました。Graphは大きく3段階に分かれた複雑な構成をしており、メインとなる骨格検出処理はTfLiteInferenceCalculatorによって行われていることがわかりました。
次回は、プログラムとGraphを変更し、検出されたデータを取り出します。
参考にさせていただいたページ
Multi-Hand Tracking on Desktop(MediaPipe Doc) https://mediapipe.readthedocs.io/en/latest/multi_hand_tracking_desktop.html
Multi-Hand Tracking (GPU) https://github.com/google/mediapipe/blob/master/mediapipe/docs/multi_hand_tracking_mobile_gpu.md
MediaPipe Visualizer https://viz.mediapipe.dev/